package com.wei.czz.framework.annex.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.common.vo.annex.AnnexGroupVo;
import com.wei.czz.framework.annex.dao.AnnexGroupDao;
import com.wei.czz.framework.annex.entity.AnnexGroupEntity;
import com.wei.czz.framework.annex.service.AnnexGroupService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-01-18 15:42:11
 * className: AnnexGroupServiceImpl
 * version: 1.0
 * description:
 */
@Service("annexGroupService")
@AllArgsConstructor
public class AnnexGroupServiceImpl extends ServiceImpl<AnnexGroupDao, AnnexGroupEntity> implements AnnexGroupService {

    private static final Logger log = LoggerFactory.getLogger(AnnexGroupServiceImpl.class);

    @Transactional
    @Override
    public void batchSaveAnnexGroup(List<AnnexGroupEntity> annexGroupList) {
        boolean bool = this.saveBatch(annexGroupList);
        log.info("批量保存附件动态配置分组完成。bool={}", bool);
    }

    @Transactional
    @Override
    public void saveAnnexGroup(Long preId, List<AnnexGroupVo> groupList) {
        if (CollectionUtils.isEmpty(groupList)) {
            log.warn("传入的附件动态配置分组参数列表为空。preId={}", preId);
            return;
        }
        /*
            查询已有分组主键
         */
        Set<Long> idSet = baseMapper.selectId(preId, CommonEnum.ZERO.getValue());

        /*
            查询已有分组
         */
        List<Long> idList = groupList.stream()
                .map(AnnexGroupVo::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        Map<Long, AnnexGroupEntity> annexGroupMap = Collections.emptyMap();
        if (!idList.isEmpty()) {
            List<AnnexGroupEntity> annexGroupList = baseMapper.selectBatchIds(idList);
            annexGroupMap = annexGroupList.stream()
                    .peek(annexGroup -> {
                        idSet.remove(annexGroup.getId());
                    })
                    .collect(Collectors.toMap(AnnexGroupEntity::getId, Function.identity()));
        }
        List<AnnexGroupEntity> saveList = new ArrayList<>();
        List<AnnexGroupEntity> updateList = new ArrayList<>();
        for (AnnexGroupVo annexGroupVo : groupList) {
            AnnexGroupEntity annexGroup = annexGroupMap.get(annexGroupVo.getId());
            boolean isSave = Objects.isNull(annexGroup);

            annexGroup = this.buildAnnexGroup(annexGroupVo, annexGroup);
            annexGroup.setPreId(preId);
            if (isSave) {
                saveList.add(annexGroup);
            } else {
                updateList.add(annexGroup);
            }
        }
        if (!saveList.isEmpty()) {
            boolean bool = this.saveBatch(saveList);
            log .info("保存附件动态配置分组完成。bool={}", bool);
        }
        if (!updateList.isEmpty()) {
            boolean bool = this.updateBatchById(updateList);
            log .info("修改附件动态配置分组完成。bool={}", bool);
        }
        if (!idSet.isEmpty()) {
            UserPo userPo = SecurityUtils.getUser();
            Date date = new Date();

            LambdaUpdateWrapper<AnnexGroupEntity> annexGroupLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            // 设置字段值
            annexGroupLambdaUpdateWrapper.set(AnnexGroupEntity::getDeleteStatus, CommonEnum.ONE.getValue())
                    .set(AnnexGroupEntity::getUpdateTime, date)
                    .set(AnnexGroupEntity::getUpdateUser, userPo.getUsername())
                    .set(AnnexGroupEntity::getUpdateUserId, userPo.getUserId());
            // 匹配
            annexGroupLambdaUpdateWrapper.in(AnnexGroupEntity::getId, idSet)
                    .eq(AnnexGroupEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
            // 删除
            int count = baseMapper.update(null, annexGroupLambdaUpdateWrapper);
            log.info("删除附件动态配置分组完成。count={}", count);
        }
    }

    @Override
    public List<AnnexGroupEntity> getAnnexGroupList(Long preId) {
        LambdaQueryWrapper<AnnexGroupEntity> annexGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        annexGroupLambdaQueryWrapper.eq(AnnexGroupEntity::getPreId, preId)
                .eq(AnnexGroupEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<AnnexGroupEntity> annexGroupList = baseMapper.selectList(annexGroupLambdaQueryWrapper);
        log.info("查询附件动态配置分组完成。preId={} isEmpty={}", preId, annexGroupList.isEmpty());
        return annexGroupList;
    }

    /**
     * 构造附件动态配置分组对象
     * @param annexGroupVo 参数对象
     * @param annexGroup   附件动态配置分组对象
     * @return 附件动态配置分组对象
     */
    private AnnexGroupEntity buildAnnexGroup(AnnexGroupVo annexGroupVo, AnnexGroupEntity annexGroup) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();
        boolean isSave = Objects.isNull(annexGroup);

        if (isSave) {
            annexGroup = new AnnexGroupEntity();
        }

        annexGroup.setId(annexGroupVo.getId())
                .setParentId(annexGroupVo.getParentId())
                .setName(annexGroupVo.getName())
                .setSort(annexGroupVo.getSort())
                .setUpdateTime(date)
                .setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue());
        if (isSave) {
            annexGroup.setDeleteStatus(CommonEnum.ZERO.getValue())
                    .setCreateTime(date)
                    .setCreateUser(userPo.getUsername())
                    .setCreateUserId(userPo.getUserId());
        } else {
            annexGroup.setUpdateUser(userPo.getUsername())
                    .setUpdateUserId(userPo.getUserId());
        }
        return annexGroup;
    }
}